

#include "stdafx.h"



   // extreme fallback texture -- 2x2 hot pink
   static int s_RGB[] = {128, 0, 255, 128, 0, 255, 128, 0, 255, 128, 0, 255};
   
   class TextureLoader : public Ogre::ManualResourceLoader
   {
   public:
	   TextureLoader(const Ogre::String &fileName ,const Ogre::String &filePath ,const Ogre::String & resGroup/*, IResourceNotification* pCallback = 0*/)
      {
         // extract the pertinent information from the Image
		    m_filePath = filePath;
			m_resGroup = resGroup;
			m_fileName = fileName;
         // m_pCallback = pCallback;
      }

      // here's where the real magic happens -- when Ogre calls for a texture, we need
      // to get it from disk and fill in the Ogre::Texture resource with it.
      void loadResource(Ogre::Resource* pResource)
      {
         Ogre::Texture* pTex = static_cast<Ogre::Texture*>(pResource);
         Ogre::Image img;

         // extract extension from filename
         size_t pos = m_filePath.find_last_of('.');
         Ogre::String ext = m_filePath.substr(pos+1);

         // prefer .dds to anything else; fall back to original filename if .dds does not exist
         //Ogre::String ddsName = m_fileName.substr(0, pos) + ".dds";

         std::ifstream i, j;
         Ogre::FileStreamDataStream* pFS = 0;
        // i.open(ddsName.c_str(), std::ios::binary);
       //  if (ext == "dds")
         {
			// if (StringUtil::endsWith(texture->getName(), ".dds"))
			// {
				// pTex->load();
			 //}
           // pFS = new Ogre::FileStreamDataStream(&i, false);
            //ext = "dds";
         }
        // else
         {
			std::locale::global(std::locale(""));

			// Ogre::UTFString df(m_filePath.c_str()) ;

            j.open(m_filePath.c_str(), std::ios::binary);
            pFS = new Ogre::FileStreamDataStream(&j, false);
         }
         Ogre::DataStreamPtr strm(pFS);

         if (!strm->size() || strm->size() == 0xffffffff)
        {
            // call out for the default texture instead
//             if (m_pCallback)
//             {
//                printf("Could not load texture '%s', calling out for default texture\n", m_fileName.substr(0, pos).c_str());
//                m_pCallback->getDefaultTexture(img);
//                assert(img.getWidth() != 0 && img.getHeight() != 0);
//                //assert(img.getFormat() != Ogre::PF_UNKNOWN); // GGJ - until Ogre applies my patch to init Image::mFormat...
//             }

            // last resort...
            //if (img.getFormat() == Ogre::PF_UNKNOWN) 
             if (img.getWidth() == 0 || img.getHeight() == 0)
             {
                // fall back to our very simple and very hardcoded hot-pink version
                Ogre::DataStreamPtr altStrm(new Ogre::MemoryDataStream(s_RGB, sizeof(s_RGB)));
                img.loadRawData(altStrm, 2, 2, Ogre::PF_R8G8B8);
                //printf("Could not load texture '%s' or its default, this texture will be pink\n", m_fileName.substr(0, pos).c_str());
             }
        }
        else
         {
            // TODO: allow for alternate resource group names
            img.load(strm,ext);
            i.close();
			j.close();
         }


// 		 Ogre::TexturePtr texture;
// 		 Ogre::Image image;
// 		 image.load(m_fileName,m_resGroup);  // absFileName is not in any loaded resource location
// 		 pTex->loadImage(image);
// 		 

          Ogre::ConstImagePtrList images;
          images.push_back(&img);
          pTex->_loadImages(images);
      }
      Ogre::String m_filePath;
	  Ogre::String m_fileName;
   private:

	  Ogre::String m_resGroup;
     // IResourceNotification* m_pCallback;
   };

   template <class _V>
   class TextureLoaderList : public std::list<_V>
   {
   public:
      TextureLoaderList() {}
      ~TextureLoaderList()
      {
         for (typename std::list<_V>::iterator it = this->begin(); it != this->end(); ++it)
         {
            delete *it;
         }
      }
   };

   // we have this for automatic cleanup of the manual loader pointers on app exit
   static TextureLoaderList<TextureLoader*> loaderList;
   typedef  std::vector<Ogre::TexturePtr> LOADTEXTURE;
   static LOADTEXTURE m_loadTexture;

   Ogre::String  addTexture(const Ogre::String &filePath,const Ogre::String &resGroupName)
    {
 

		for (TextureLoaderList<TextureLoader*>::iterator it = loaderList.begin(); it != loaderList.end(); ++it)
		{
			if ( (*it)->m_filePath == filePath  )
			{
				return (*it)->m_fileName;
			}
		}

		Ogre::String  outBasename;
		String path = filePath;
		// Replace \ with / first
		std::replace( path.begin(), path.end(), '\\', '/' );
		// split based on final /
		size_t i = path.find_last_of('/');
		if (i == String::npos)
		{
			outBasename = filePath;
		}
		else
		{
			outBasename = path.substr(i+1, path.size() - i - 1);
		}


	   Ogre::TextureManager* pTexMgr = Ogre::Root::getSingleton().getTextureManager();
       TextureLoader* pLoader = new TextureLoader(outBasename,filePath,resGroupName);
       loaderList.push_back(pLoader);
 
       Ogre::TexturePtr pTex = pTexMgr->createOrRetrieve(
		  outBasename, 
          resGroupName,
          true,
          pLoader
       ).first;
	   m_loadTexture.push_back(pTex);
	
       pTex->_notifyOrigin(filePath);
	 //  pTex->load();

	   return outBasename;
    }
 